Read Data

#install.packages("sqldf")    #https://cran.r-project.org/web/packages/sqldf/sqldf.pdf   Permite realizar búsquedas sobre dataframes con sintaxis sql
library(sqldf)
#install.packages("fmsb")  #Several utility functions for the book entitled "Practices of Medical and Health Data Analysis using R" (Pearson Education Japan, 2007) with Japanese demographic data and some demographic analysis related functions.
library(fmsb)
library(plotly)  #https://plot.ly/r/
video_games<-read.csv("recursos/vgsales.csv")
typeof(video_games)
[1] "list"
head(video_games)
video_games$Year <- ordered(video_games$Year)
video_games <- video_games[video_games$Year<2017,]
video_games

Explore Sales by Year and Platform

ByYear<-sqldf("SELECT Platform, Year, sum(NA_Sales) as AME, sum(EU_Sales) as EU,sum(JP_Sales) as JP, sum(Other_Sales) as Other, sum(Global_Sales) as Global from video_games group by Platform, Year order by Year,Platform")

Ventas anuales. Todas las Plataformas

All<- sqldf("SELECT Year, sum(NA_Sales) as AME, sum(EU_Sales) as EU,sum(JP_Sales) as JP, sum(Other_Sales) as Other, sum(Global_Sales) as Global from df group by Year order by Year")
#https://plot.ly/r/line-charts/
plot_ly(All,type = 'scatter', mode = 'lines') %>%
  add_trace(y=All$Global,x=All$Year,name='Global Sale',mode = 'lines')%>%
  add_trace(y=All$AME,x=All$Year,mode = 'lines',name='American Sale')%>%
  add_trace(y=All$EU,x=All$Year,mode = 'lines',name='European Sale')%>%
  add_trace(y=All$JP,x=All$Year,name='Japen Sales',mode = 'lines')%>%
  add_trace(y=All$Other,x=All$Year,name='Other Sale',mode = 'lines')%>%
  layout(title = "Ventas de Videjuegos Anuales por Región",
         xaxis = list(title = "Años"),
         yaxis = list (title = "Ventas en Millones"))

Lo mismo pero solo para un par de tipos de consola: PS2, PS3 y PS4.

PS2<-subset(ByYear,Platform=="PS2",select = Platform:Global)
PS3<-subset(ByYear,Platform=="PS3",select = Platform:Global)
PS4<-subset(ByYear,Platform=="PS4",select = Platform:Global)
plot_ly(ByYear,type = 'scatter', mode = 'lines') %>%
  add_trace(y=PS2$Global,x=PS2$Year,name='Global Sale PS2',mode = 'lines+markers') %>%
  add_trace(y=PS3$Global,x=PS3$Year,name='Global Sale PS3',mode = 'lines+markers') %>%
  add_trace(y=PS4$Global,x=PS4$Year,name='Global Sale PS4',mode = 'lines+markers') %>%
  layout(title = "Evolución Ventas PlayStation",
         xaxis = list(title = "Años"),
         yaxis = list (title = "Ventas en Millones"))

Detalle PS2 por año y región

PS2<-ByYear[ByYear$Platform=='PS2',]
plot_ly(PS2, type = 'bar', name = 'Ventas PS2 por Región') %>%
  add_trace(y=PS2$AME,x=PS2$Year,name='America',mode = 'bar') %>%
  add_trace(y=PS2$EU,x=PS2$Year,name='Europa',mode = 'bar') %>%
  add_trace(y=PS2$JP,x=PS2$Year,name='Japan',mode = 'bar') %>%
  add_trace(y=PS2$Other,x=PS2$Year,name='Other',mode = 'bar') %>%
  add_trace(y=PS2$Other,x=PS2$Year,name='Global',mode = 'bar')%>%
  layout(title = "Ventas PS2 por año y Región",
         scene = list(
           xaxis = list(title = "Año"), 
           yaxis = list(title = "Ventas")))

PS3<-ByYear[ByYear$Platform=='PS3',]
plot_ly(PS3, type = 'bar', name = 'Ventas PS3 por Región') %>%
  add_trace(y=PS3$AME,x=PS3$Year,name='America',mode = 'bar') %>%
  add_trace(y=PS3$EU,x=PS3$Year,name='Europa',mode = 'bar') %>%
  add_trace(y=PS3$JP,x=PS3$Year,name='Japan',mode = 'bar') %>%
  add_trace(y=PS3$Other,x=PS3$Year,name='Other',mode = 'bar') %>%
  add_trace(y=PS3$Other,x=PS3$Year,name='Global',mode = 'bar')%>%
  layout(title = "Ventas PS3 por año y Región",
         scene = list(
           xaxis = list(title = "Año"), 
           yaxis = list(title = "Ventas")))

PS4<-ByYear[ByYear$Platform=='PS4',]
plot_ly(PS4, type = 'bar', name = 'Ventas PS4 por Región') %>%
  add_trace(y=PS4$AME,x=PS4$Year,name='America',mode = 'bar') %>%
  add_trace(y=PS4$EU,x=PS4$Year,name='Europa',mode = 'bar') %>%
  add_trace(y=PS4$JP,x=PS4$Year,name='Japan',mode = 'bar') %>%
  add_trace(y=PS4$Other,x=PS4$Year,name='Other',mode = 'bar') %>%
  add_trace(y=PS4$Other,x=PS4$Year,name='Global',mode = 'bar')%>%
  layout(title = "Ventas PS4 por año y Región",
         scene = list(
           xaxis = list(title = "Año"), 
           yaxis = list(title = "Ventas")))

Ventas globales por plataforma (principales plataformas)

Platform_data<- sqldf("SELECT Platform, sum(NA_Sales) as AME, sum(EU_Sales) as EU,sum(JP_Sales) as JP, sum(Other_Sales) as Other, sum(Global_Sales) as Global from video_games where platform in('DS','PS','PS2','PS3','Wii','X360','PSP','PS4') group by Platform order by Platform")
Platform_data
plot_ly(Platform_data, labels = ~Platform, values = ~Global, type = 'pie') %>%
  layout(title = 'Ventas totales por consola',
         xaxis = list(showgrid = TRUE, zeroline = TRUE, showticklabels = TRUE),
         yaxis = list(showgrid = TRUE, zeroline = TRUE, showticklabels = TRUE))

plot_ly(Platform_data, labels = ~Platform, values = ~EU, type = 'pie') %>%
  layout(title = 'Ventas totales por consola',
         xaxis = list(showgrid = TRUE, zeroline = TRUE, showticklabels = TRUE),
         yaxis = list(showgrid = TRUE, zeroline = TRUE, showticklabels = TRUE))

Ventas globales por genero

Genre_data<- sqldf("SELECT Genre, sum(NA_Sales) as AME, sum(EU_Sales) as EU,sum(JP_Sales) as JP, sum(Other_Sales) as Other, sum(Global_Sales) as Global from video_games  group by Genre order by Platform")
Genre_data
plot_ly(Genre_data, x = ~Genre, y = ~Global, type = 'bar', text = text,
        marker = list(color = 'rgb(158,202,225)',
                      line = list(color = 'rgb(8,48,107)',
                                  width = 0.5))) %>%
  layout(title = "Ventas Globales por Genero.",
         xaxis = list(title = "",size = 40,color = "#7f7f44"),
         yaxis = list(title = ""))

plot_ly(Genre_data, x = ~Genre, y = ~AME, type = 'bar', text = text,
        marker = list(color = 'rgb(158,202,225)',
                      line = list(color = 'rgb(8,48,107)',
                                  width = 0.5))) %>%
  layout(title = "Ventas Globales por Genero.",
         xaxis = list(title = "",size = 40,color = "#7f7f44"),
         yaxis = list(title = ""))

plot_ly(Genre_data, x = ~Genre, y = ~EU, type = 'bar', text = text,
        marker = list(color = 'rgb(158,202,225)',
                      line = list(color = 'rgb(8,48,107)',
                                  width = 0.5))) %>%
  layout(title = "Ventas Globales por Genero.",
         xaxis = list(title = "",size = 40,color = "#7f7f44"),
         yaxis = list(title = ""))

plot_ly(Genre_data, x = ~Genre, y = ~JP, type = 'bar', text = text,
        marker = list(color = 'rgb(158,202,225)',
                      line = list(color = 'rgb(8,48,107)',
                                  width = 0.5))) %>%
  layout(title = "Ventas Globales por Genero.",
         xaxis = list(title = "",size = 40,color = "#7f7f44"),
         yaxis = list(title = ""))

Por plataforma y Genero

Genre_plat_data<- sqldf("SELECT Platform, Genre, sum(NA_Sales) as AME, sum(EU_Sales) as EU,sum(JP_Sales) as JP, sum(Other_Sales) as Other, sum(Global_Sales) as Global from video_games group by Platform, Genre order by Platform")
gpd_ps4<-Genre_plat_data[Genre_plat_data$Platform=='PS4',]
gpd_ps4
plot_ly(gpd_ps4, labels = ~Genre, values = ~Global) %>%
  add_pie(hole = 0.6) %>%
  layout(title = "Ventas Ps4 por Género",  showlegend = F,
         xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
         yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBSZWFkIERhdGEKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJzcWxkZiIpICAgICNodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvc3FsZGYvc3FsZGYucGRmICAgUGVybWl0ZSByZWFsaXphciBiw7pzcXVlZGFzIHNvYnJlIGRhdGFmcmFtZXMgY29uIHNpbnRheGlzIHNxbApsaWJyYXJ5KHNxbGRmKQojaW5zdGFsbC5wYWNrYWdlcygiZm1zYiIpICAjU2V2ZXJhbCB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgdGhlIGJvb2sgZW50aXRsZWQgIlByYWN0aWNlcyBvZiBNZWRpY2FsIGFuZCBIZWFsdGggRGF0YSBBbmFseXNpcyB1c2luZyBSIiAoUGVhcnNvbiBFZHVjYXRpb24gSmFwYW4sIDIwMDcpIHdpdGggSmFwYW5lc2UgZGVtb2dyYXBoaWMgZGF0YSBhbmQgc29tZSBkZW1vZ3JhcGhpYyBhbmFseXNpcyByZWxhdGVkIGZ1bmN0aW9ucy4KbGlicmFyeShmbXNiKQpsaWJyYXJ5KHBsb3RseSkgICNodHRwczovL3Bsb3QubHkvci8KCnZpZGVvX2dhbWVzPC1yZWFkLmNzdigicmVjdXJzb3MvdmdzYWxlcy5jc3YiKQp0eXBlb2YodmlkZW9fZ2FtZXMpCmhlYWQodmlkZW9fZ2FtZXMpCgp2aWRlb19nYW1lcyRZZWFyIDwtIG9yZGVyZWQodmlkZW9fZ2FtZXMkWWVhcikKdmlkZW9fZ2FtZXMgPC0gdmlkZW9fZ2FtZXNbdmlkZW9fZ2FtZXMkWWVhcjwyMDE3LF0KdmlkZW9fZ2FtZXMKYGBgCgojIEV4cGxvcmUgU2FsZXMgYnkgWWVhciBhbmQgUGxhdGZvcm0gey50YWJzZXR9CmBgYHtyfQpCeVllYXI8LXNxbGRmKCJTRUxFQ1QgUGxhdGZvcm0sIFllYXIsIHN1bShOQV9TYWxlcykgYXMgQU1FLCBzdW0oRVVfU2FsZXMpIGFzIEVVLHN1bShKUF9TYWxlcykgYXMgSlAsIHN1bShPdGhlcl9TYWxlcykgYXMgT3RoZXIsIHN1bShHbG9iYWxfU2FsZXMpIGFzIEdsb2JhbCBmcm9tIHZpZGVvX2dhbWVzIGdyb3VwIGJ5IFBsYXRmb3JtLCBZZWFyIG9yZGVyIGJ5IFllYXIsUGxhdGZvcm0iKQpgYGAKCiNWZW50YXMgYW51YWxlcy4gVG9kYXMgbGFzIFBsYXRhZm9ybWFzCmBgYHtyfQpBbGw8LSBzcWxkZigiU0VMRUNUIFllYXIsIHN1bShOQV9TYWxlcykgYXMgQU1FLCBzdW0oRVVfU2FsZXMpIGFzIEVVLHN1bShKUF9TYWxlcykgYXMgSlAsIHN1bShPdGhlcl9TYWxlcykgYXMgT3RoZXIsIHN1bShHbG9iYWxfU2FsZXMpIGFzIEdsb2JhbCBmcm9tIGRmIGdyb3VwIGJ5IFllYXIgb3JkZXIgYnkgWWVhciIpCgoKI2h0dHBzOi8vcGxvdC5seS9yL2xpbmUtY2hhcnRzLwpwbG90X2x5KEFsbCx0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ2xpbmVzJykgJT4lCiAgYWRkX3RyYWNlKHk9QWxsJEdsb2JhbCx4PUFsbCRZZWFyLG5hbWU9J0dsb2JhbCBTYWxlJyxtb2RlID0gJ2xpbmVzJyklPiUKICBhZGRfdHJhY2UoeT1BbGwkQU1FLHg9QWxsJFllYXIsbW9kZSA9ICdsaW5lcycsbmFtZT0nQW1lcmljYW4gU2FsZScpJT4lCiAgYWRkX3RyYWNlKHk9QWxsJEVVLHg9QWxsJFllYXIsbW9kZSA9ICdsaW5lcycsbmFtZT0nRXVyb3BlYW4gU2FsZScpJT4lCiAgYWRkX3RyYWNlKHk9QWxsJEpQLHg9QWxsJFllYXIsbmFtZT0nSmFwZW4gU2FsZXMnLG1vZGUgPSAnbGluZXMnKSU+JQogIGFkZF90cmFjZSh5PUFsbCRPdGhlcix4PUFsbCRZZWFyLG5hbWU9J090aGVyIFNhbGUnLG1vZGUgPSAnbGluZXMnKSU+JQogIGxheW91dCh0aXRsZSA9ICJWZW50YXMgZGUgVmlkZWp1ZWdvcyBBbnVhbGVzIHBvciBSZWdpw7NuIiwKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkHDsW9zIiksCiAgICAgICAgIHlheGlzID0gbGlzdCAodGl0bGUgPSAiVmVudGFzIGVuIE1pbGxvbmVzIikpCmBgYAoKTG8gbWlzbW8gcGVybyBzb2xvIHBhcmEgdW4gcGFyIGRlIHRpcG9zIGRlIGNvbnNvbGE6IFBTMiwgUFMzIHkgUFM0LgpgYGB7ciByZXN1bHRzPSdhc2lzJyxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9ClBTMjwtc3Vic2V0KEJ5WWVhcixQbGF0Zm9ybT09IlBTMiIsc2VsZWN0ID0gUGxhdGZvcm06R2xvYmFsKQpQUzM8LXN1YnNldChCeVllYXIsUGxhdGZvcm09PSJQUzMiLHNlbGVjdCA9IFBsYXRmb3JtOkdsb2JhbCkKUFM0PC1zdWJzZXQoQnlZZWFyLFBsYXRmb3JtPT0iUFM0IixzZWxlY3QgPSBQbGF0Zm9ybTpHbG9iYWwpCgpwbG90X2x5KEJ5WWVhcix0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ2xpbmVzJykgJT4lCiAgYWRkX3RyYWNlKHk9UFMyJEdsb2JhbCx4PVBTMiRZZWFyLG5hbWU9J0dsb2JhbCBTYWxlIFBTMicsbW9kZSA9ICdsaW5lcyttYXJrZXJzJykgJT4lCiAgYWRkX3RyYWNlKHk9UFMzJEdsb2JhbCx4PVBTMyRZZWFyLG5hbWU9J0dsb2JhbCBTYWxlIFBTMycsbW9kZSA9ICdsaW5lcyttYXJrZXJzJykgJT4lCiAgYWRkX3RyYWNlKHk9UFM0JEdsb2JhbCx4PVBTNCRZZWFyLG5hbWU9J0dsb2JhbCBTYWxlIFBTNCcsbW9kZSA9ICdsaW5lcyttYXJrZXJzJykgJT4lCiAgbGF5b3V0KHRpdGxlID0gIkV2b2x1Y2nDs24gVmVudGFzIFBsYXlTdGF0aW9uIiwKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkHDsW9zIiksCiAgICAgICAgIHlheGlzID0gbGlzdCAodGl0bGUgPSAiVmVudGFzIGVuIE1pbGxvbmVzIikpCmBgYAoKRGV0YWxsZSBQUzIgcG9yIGHDsW8geSByZWdpw7NuCmBgYHtyIHJlc3VsdHM9J2FzaXMnLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0KUFMyPC1CeVllYXJbQnlZZWFyJFBsYXRmb3JtPT0nUFMyJyxdCgpwbG90X2x5KFBTMiwgdHlwZSA9ICdiYXInLCBuYW1lID0gJ1ZlbnRhcyBQUzIgcG9yIFJlZ2nDs24nKSAlPiUKICBhZGRfdHJhY2UoeT1QUzIkQU1FLHg9UFMyJFllYXIsbmFtZT0nQW1lcmljYScsbW9kZSA9ICdiYXInKSAlPiUKICBhZGRfdHJhY2UoeT1QUzIkRVUseD1QUzIkWWVhcixuYW1lPSdFdXJvcGEnLG1vZGUgPSAnYmFyJykgJT4lCiAgYWRkX3RyYWNlKHk9UFMyJEpQLHg9UFMyJFllYXIsbmFtZT0nSmFwYW4nLG1vZGUgPSAnYmFyJykgJT4lCiAgYWRkX3RyYWNlKHk9UFMyJE90aGVyLHg9UFMyJFllYXIsbmFtZT0nT3RoZXInLG1vZGUgPSAnYmFyJykgJT4lCiAgYWRkX3RyYWNlKHk9UFMyJE90aGVyLHg9UFMyJFllYXIsbmFtZT0nR2xvYmFsJyxtb2RlID0gJ2JhcicpJT4lCiAgbGF5b3V0KHRpdGxlID0gIlZlbnRhcyBQUzIgcG9yIGHDsW8geSBSZWdpw7NuIiwKICAgICAgICAgc2NlbmUgPSBsaXN0KAogICAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJBw7FvIiksIAogICAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJWZW50YXMiKSkpCgpQUzM8LUJ5WWVhcltCeVllYXIkUGxhdGZvcm09PSdQUzMnLF0KCnBsb3RfbHkoUFMzLCB0eXBlID0gJ2JhcicsIG5hbWUgPSAnVmVudGFzIFBTMyBwb3IgUmVnacOzbicpICU+JQogIGFkZF90cmFjZSh5PVBTMyRBTUUseD1QUzMkWWVhcixuYW1lPSdBbWVyaWNhJyxtb2RlID0gJ2JhcicpICU+JQogIGFkZF90cmFjZSh5PVBTMyRFVSx4PVBTMyRZZWFyLG5hbWU9J0V1cm9wYScsbW9kZSA9ICdiYXInKSAlPiUKICBhZGRfdHJhY2UoeT1QUzMkSlAseD1QUzMkWWVhcixuYW1lPSdKYXBhbicsbW9kZSA9ICdiYXInKSAlPiUKICBhZGRfdHJhY2UoeT1QUzMkT3RoZXIseD1QUzMkWWVhcixuYW1lPSdPdGhlcicsbW9kZSA9ICdiYXInKSAlPiUKICBhZGRfdHJhY2UoeT1QUzMkT3RoZXIseD1QUzMkWWVhcixuYW1lPSdHbG9iYWwnLG1vZGUgPSAnYmFyJyklPiUKICBsYXlvdXQodGl0bGUgPSAiVmVudGFzIFBTMyBwb3IgYcOxbyB5IFJlZ2nDs24iLAogICAgICAgICBzY2VuZSA9IGxpc3QoCiAgICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkHDsW8iKSwgCiAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlZlbnRhcyIpKSkKClBTNDwtQnlZZWFyW0J5WWVhciRQbGF0Zm9ybT09J1BTNCcsXQoKcGxvdF9seShQUzQsIHR5cGUgPSAnYmFyJywgbmFtZSA9ICdWZW50YXMgUFM0IHBvciBSZWdpw7NuJykgJT4lCiAgYWRkX3RyYWNlKHk9UFM0JEFNRSx4PVBTNCRZZWFyLG5hbWU9J0FtZXJpY2EnLG1vZGUgPSAnYmFyJykgJT4lCiAgYWRkX3RyYWNlKHk9UFM0JEVVLHg9UFM0JFllYXIsbmFtZT0nRXVyb3BhJyxtb2RlID0gJ2JhcicpICU+JQogIGFkZF90cmFjZSh5PVBTNCRKUCx4PVBTNCRZZWFyLG5hbWU9J0phcGFuJyxtb2RlID0gJ2JhcicpICU+JQogIGFkZF90cmFjZSh5PVBTNCRPdGhlcix4PVBTNCRZZWFyLG5hbWU9J090aGVyJyxtb2RlID0gJ2JhcicpICU+JQogIGFkZF90cmFjZSh5PVBTNCRPdGhlcix4PVBTNCRZZWFyLG5hbWU9J0dsb2JhbCcsbW9kZSA9ICdiYXInKSU+JQogIGxheW91dCh0aXRsZSA9ICJWZW50YXMgUFM0IHBvciBhw7FvIHkgUmVnacOzbiIsCiAgICAgICAgIHNjZW5lID0gbGlzdCgKICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiQcOxbyIpLCAKICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiVmVudGFzIikpKQoKYGBgCgpWZW50YXMgZ2xvYmFsZXMgcG9yIHBsYXRhZm9ybWEgKHByaW5jaXBhbGVzIHBsYXRhZm9ybWFzKQpgYGB7cn0KClBsYXRmb3JtX2RhdGE8LSBzcWxkZigiU0VMRUNUIFBsYXRmb3JtLCBzdW0oTkFfU2FsZXMpIGFzIEFNRSwgc3VtKEVVX1NhbGVzKSBhcyBFVSxzdW0oSlBfU2FsZXMpIGFzIEpQLCBzdW0oT3RoZXJfU2FsZXMpIGFzIE90aGVyLCBzdW0oR2xvYmFsX1NhbGVzKSBhcyBHbG9iYWwgZnJvbSB2aWRlb19nYW1lcyB3aGVyZSBwbGF0Zm9ybSBpbignRFMnLCdQUycsJ1BTMicsJ1BTMycsJ1dpaScsJ1gzNjAnLCdQU1AnLCdQUzQnKSBncm91cCBieSBQbGF0Zm9ybSBvcmRlciBieSBQbGF0Zm9ybSIpClBsYXRmb3JtX2RhdGEKCnBsb3RfbHkoUGxhdGZvcm1fZGF0YSwgbGFiZWxzID0gflBsYXRmb3JtLCB2YWx1ZXMgPSB+R2xvYmFsLCB0eXBlID0gJ3BpZScpICU+JQogIGxheW91dCh0aXRsZSA9ICdWZW50YXMgdG90YWxlcyBwb3IgY29uc29sYScsCiAgICAgICAgIHhheGlzID0gbGlzdChzaG93Z3JpZCA9IFRSVUUsIHplcm9saW5lID0gVFJVRSwgc2hvd3RpY2tsYWJlbHMgPSBUUlVFKSwKICAgICAgICAgeWF4aXMgPSBsaXN0KHNob3dncmlkID0gVFJVRSwgemVyb2xpbmUgPSBUUlVFLCBzaG93dGlja2xhYmVscyA9IFRSVUUpKQoKCnBsb3RfbHkoUGxhdGZvcm1fZGF0YSwgbGFiZWxzID0gflBsYXRmb3JtLCB2YWx1ZXMgPSB+RVUsIHR5cGUgPSAncGllJykgJT4lCiAgbGF5b3V0KHRpdGxlID0gJ1ZlbnRhcyB0b3RhbGVzIHBvciBjb25zb2xhJywKICAgICAgICAgeGF4aXMgPSBsaXN0KHNob3dncmlkID0gVFJVRSwgemVyb2xpbmUgPSBUUlVFLCBzaG93dGlja2xhYmVscyA9IFRSVUUpLAogICAgICAgICB5YXhpcyA9IGxpc3Qoc2hvd2dyaWQgPSBUUlVFLCB6ZXJvbGluZSA9IFRSVUUsIHNob3d0aWNrbGFiZWxzID0gVFJVRSkpCgpgYGAKClZlbnRhcyBnbG9iYWxlcyBwb3IgZ2VuZXJvIApgYGB7cn0KR2VucmVfZGF0YTwtIHNxbGRmKCJTRUxFQ1QgR2VucmUsIHN1bShOQV9TYWxlcykgYXMgQU1FLCBzdW0oRVVfU2FsZXMpIGFzIEVVLHN1bShKUF9TYWxlcykgYXMgSlAsIHN1bShPdGhlcl9TYWxlcykgYXMgT3RoZXIsIHN1bShHbG9iYWxfU2FsZXMpIGFzIEdsb2JhbCBmcm9tIHZpZGVvX2dhbWVzICBncm91cCBieSBHZW5yZSBvcmRlciBieSBQbGF0Zm9ybSIpCkdlbnJlX2RhdGEKCnBsb3RfbHkoR2VucmVfZGF0YSwgeCA9IH5HZW5yZSwgeSA9IH5HbG9iYWwsIHR5cGUgPSAnYmFyJywgdGV4dCA9IHRleHQsCiAgICAgICAgbWFya2VyID0gbGlzdChjb2xvciA9ICdyZ2IoMTU4LDIwMiwyMjUpJywKICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gJ3JnYig4LDQ4LDEwNyknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAwLjUpKSkgJT4lCiAgbGF5b3V0KHRpdGxlID0gIlZlbnRhcyBHbG9iYWxlcyBwb3IgR2VuZXJvLiIsCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICIiLHNpemUgPSA0MCxjb2xvciA9ICIjN2Y3ZjQ0IiksCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICIiKSkKCnBsb3RfbHkoR2VucmVfZGF0YSwgeCA9IH5HZW5yZSwgeSA9IH5BTUUsIHR5cGUgPSAnYmFyJywgdGV4dCA9IHRleHQsCiAgICAgICAgbWFya2VyID0gbGlzdChjb2xvciA9ICdyZ2IoMTU4LDIwMiwyMjUpJywKICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gJ3JnYig4LDQ4LDEwNyknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAwLjUpKSkgJT4lCiAgbGF5b3V0KHRpdGxlID0gIlZlbnRhcyBHbG9iYWxlcyBwb3IgR2VuZXJvLiIsCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICIiLHNpemUgPSA0MCxjb2xvciA9ICIjN2Y3ZjQ0IiksCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICIiKSkKCnBsb3RfbHkoR2VucmVfZGF0YSwgeCA9IH5HZW5yZSwgeSA9IH5FVSwgdHlwZSA9ICdiYXInLCB0ZXh0ID0gdGV4dCwKICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJ3JnYigxNTgsMjAyLDIyNSknLAogICAgICAgICAgICAgICAgICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAncmdiKDgsNDgsMTA3KScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNSkpKSAlPiUKICBsYXlvdXQodGl0bGUgPSAiVmVudGFzIEdsb2JhbGVzIHBvciBHZW5lcm8uIiwKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIsc2l6ZSA9IDQwLGNvbG9yID0gIiM3ZjdmNDQiKSwKICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiIpKQoKcGxvdF9seShHZW5yZV9kYXRhLCB4ID0gfkdlbnJlLCB5ID0gfkpQLCB0eXBlID0gJ2JhcicsIHRleHQgPSB0ZXh0LAogICAgICAgIG1hcmtlciA9IGxpc3QoY29sb3IgPSAncmdiKDE1OCwyMDIsMjI1KScsCiAgICAgICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICdyZ2IoOCw0OCwxMDcpJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoID0gMC41KSkpICU+JQogIGxheW91dCh0aXRsZSA9ICJWZW50YXMgR2xvYmFsZXMgcG9yIEdlbmVyby4iLAogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiIixzaXplID0gNDAsY29sb3IgPSAiIzdmN2Y0NCIpLAogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiIikpCgpgYGAKCiMjIFBvciBwbGF0YWZvcm1hIHkgR2VuZXJvCmBgYHtyfQpHZW5yZV9wbGF0X2RhdGE8LSBzcWxkZigiU0VMRUNUIFBsYXRmb3JtLCBHZW5yZSwgc3VtKE5BX1NhbGVzKSBhcyBBTUUsIHN1bShFVV9TYWxlcykgYXMgRVUsc3VtKEpQX1NhbGVzKSBhcyBKUCwgc3VtKE90aGVyX1NhbGVzKSBhcyBPdGhlciwgc3VtKEdsb2JhbF9TYWxlcykgYXMgR2xvYmFsIGZyb20gdmlkZW9fZ2FtZXMgZ3JvdXAgYnkgUGxhdGZvcm0sIEdlbnJlIG9yZGVyIGJ5IFBsYXRmb3JtIikKCmdwZF9wczQ8LUdlbnJlX3BsYXRfZGF0YVtHZW5yZV9wbGF0X2RhdGEkUGxhdGZvcm09PSdQUzQnLF0KZ3BkX3BzNApwbG90X2x5KGdwZF9wczQsIGxhYmVscyA9IH5HZW5yZSwgdmFsdWVzID0gfkdsb2JhbCkgJT4lCiAgYWRkX3BpZShob2xlID0gMC42KSAlPiUKICBsYXlvdXQodGl0bGUgPSAiVmVudGFzIFBzNCBwb3IgR8OpbmVybyIsICBzaG93bGVnZW5kID0gRiwKICAgICAgICAgeGF4aXMgPSBsaXN0KHNob3dncmlkID0gRkFMU0UsIHplcm9saW5lID0gRkFMU0UsIHNob3d0aWNrbGFiZWxzID0gRkFMU0UpLAogICAgICAgICB5YXhpcyA9IGxpc3Qoc2hvd2dyaWQgPSBGQUxTRSwgemVyb2xpbmUgPSBGQUxTRSwgc2hvd3RpY2tsYWJlbHMgPSBGQUxTRSkpCgpgYGAKCgoKCg==